package ar.com.sectorwine.controllers;

import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import ar.com.sectorwine.dto.UsuarioABMDTO;
import ar.com.sectorwine.dto.UsuarioABMDTOMapper;
import ar.com.sectorwine.entities.Users;
import ar.com.sectorwine.services.UsuarioService;

@Controller
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class UsuariosController {

	@Autowired
	private UsuarioService usuarioService;

	@Autowired
	private Validator validator;

	@Autowired
	private UsuarioABMDTOMapper usuarioABMDTOMapper;

	private static final Logger logger = LoggerFactory
			.getLogger(RegistroController.class);

	@RequestMapping(value = "/obtener_detalles_usuario", method = RequestMethod.GET)
	public ModelAndView getUsuario(final HttpServletRequest request,
			Principal principal) {

		final String currentUsername = principal.getName();

		Users usuarioActual = usuarioService.obtenerUsuario(currentUsername);

		UsuarioABMDTO usuarioDTO = usuarioABMDTOMapper
				.obtenerDTODesdeObjetoDelDominio(usuarioActual);

		return new ModelAndView("usuarios/registro", "usuario", usuarioDTO);

	}

	@RequestMapping(value = "usuarios_listar", method = RequestMethod.GET)
	public ModelAndView lista(Locale locale, Model model, Principal principal) {
		
		logger.info("Welcome home! the client locale is " + locale.toString());
		
		ModelAndView mav = new ModelAndView("usuarios/usuarios_listar");
		List<UsuarioABMDTO> usuarios_cargados = new ArrayList<UsuarioABMDTO>();
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		usuarios_cargados.add(usuarioABMDTOMapper
				.obtenerDTODesdeObjetoDelDominio(usuarioActual));
		mav.addObject("usuariosList", usuarios_cargados);
		return mav;
	}

	@RequestMapping(value = "usuarios_modificar", method = RequestMethod.GET)
	public ModelAndView modificar(Locale locale, Model model,
			Principal principal) {

		logger.info("Welcome home! the client locale is " + locale.toString());

		ModelAndView mav = new ModelAndView("usuarios/usuarios_modificar");

		Users usuario_buscado = usuarioService.getUsuario(principal.getName());

		mav.addObject("usuario", usuarioABMDTOMapper
				.obtenerDTODesdeObjetoDelDominio(usuario_buscado));

		return mav;
	}

	@RequestMapping(value = "usuarios_modificar", method = RequestMethod.POST)
	public ModelAndView modificar(
			@Valid @ModelAttribute("usuario") UsuarioABMDTO usuarioDTO,
			BindingResult result, SessionStatus status) {

		logger.info("controller");
		Users usuario = usuarioABMDTOMapper
				.obtenerObjetoDelDominioDesdeDTO(usuarioDTO);

		Set<ConstraintViolation<UsuarioABMDTO>> failures = validator
				.validate(usuarioDTO);

		if (failures.size() == 0) {
			if (usuario != null) {
				usuarioService.modificarUsuario(usuario);
				status.setComplete();
				ModelAndView mav = new ModelAndView("home");
				mav.addObject("usuario", usuarioDTO);
				return mav;
			} else {
				ModelAndView mav = new ModelAndView(
						"usuarios/usuarios_modificar");
				mav.addObject("usuario", usuarioDTO);
				return mav;
			}
		} else {
			ModelAndView mav = new ModelAndView("usuarios/usuarios_modificar");
			mav.addObject("usuario", usuarioDTO);
			for (Object o : failures) {
				logger.info(o.toString());
			}
			return mav;
		}

	}

	@RequestMapping(value = "usuarios_baja", method = RequestMethod.POST)
	public ModelAndView darBajaLogica(Locale locale, Model model,
			Principal principal) {

		logger.info("controller");

		ModelAndView mav = new ModelAndView("j_spring_security_logout");

		Users usuario_buscado = usuarioService.getUsuario(principal.getName());
		mav.addObject("resultado", usuarioService.bajaUsuario(usuario_buscado));

		return mav;
	}

	@RequestMapping(value = "usuarios_perfil", method = RequestMethod.GET)
	public ModelAndView verPerfil(Locale locale, Model model,
			@RequestParam String idUser) {
		ModelAndView mav = new ModelAndView("usuarios/usuarios_perfil");
		mav.addObject("usuario", usuarioService.getUsuario(idUser));
		return mav;
	}

}
